Observable
中文直譯為可觀測物件
我比較喜歡稱他為 被訂閱者,簡單又直觀
訂閱的世界裡有三個名詞
Subscriber
訂閱者: 可以訂閱別人Observable
被訂閱者: 可以被訂閱Subscribe
訂閱: 動詞,訂閱本身的行為每當被訂閱者完成一部影片,會發出通知,
告訴所有訂閱他的訂閱者,說:「欸欸我出一個新的影片囉,快叫大家來看!」
Subscriber 訂閱者 -> (Subscribe) -> Observable 被訂閱者
中文為: 『訂閱者 訂閱了 被訂閱者』
這整個過程則稱為 訂閱事件
依照上一次的範例來看,在store.component.ts
中
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
this.http.get(url).subscribe(result => {
console.log(result);
});
}
this.http.get(url)
代表被訂閱者
.subscribe()
表示訂閱的動作
subscribe()
的裡面則是一個callBack
函式,把回來的資料result
給印出來
也可以寫成這樣,讓變數getData$
成為Observable
最後再subscribe()
他
export class StoreComponent {
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
let getData$ = this.http.get(url);
getData$.subscribe(
result => {
console.log(result);
}
)
}
}
在變數命名慣例上,會對
Observable
物件尾端加上錢字號$
後綴
$
能讓人們意會到這個物件是資料流,而非資料本身
也可以長成這樣子
使用Subscription
物件來集中管理所有的 訂閱事件
export class StoreComponent {
subscription = new Subscription();
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
let getData$ = this.http.get(url);
this.subscription.add(
getData$.subscribe(
result => {
console.log(result);
}
)
)
}
}
但這個樣子形式還是有點醜,似乎跟原本一樣,沒有什麼意義
所以我們可以再加上 RxJS
的 .pipe()
方法,把要處理的事情都丟進去
.tap()
就是在pipe()
管線中要他執行某些事情 Do Something 的意思
把要做的事情、醜醜的code都包裝起來,對外僅露出短短的一行getData$.subscribe()
export class StoreComponent {
subscription = new Subscription();
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
let getData$ = this.http.get(url).pipe(
tap(
result => {
console.log(result);
}
)
);
this.subscription.add(getData$.subscribe());
}
}
或者這樣,
先將資料流subscribe()
,再放進Subscription
物件中
export class StoreComponent {
subscription = new Subscription();
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
let getData$ = this.http.get(url).pipe(
tap(
result => {
console.log(result);
}
)
).subscribe();
this.subscription.add(getData$);
}
}
為什麼推薦這樣子寫呢?
因為等專案大一點之後,如果用方法一
可能會看到類似如下的程式碼
constructor(private http: HttpClient) {
let url = 'https://63403667d1fcddf69cb402b7.mockapi.io/api/v1/weapons';
let getData$ = this.http.get(url);
this.subscription.add(
getData$.subscribe(
result => {
console.log(result);
}
)
)
...
this.subscription.add(
getData$.subscribe(
result => {
console.log(result);
}
)
)
}
運行結果
而使用Subscription
物件
this.subscription.add(getData$);
this.subscription.add(getData$);
this.subscription.add(getData$);
運行結果
把訂閱集中、收集起來,不僅能確保只做了一次訂閱
對於後續接手的人來說,也能很明確知道這個元件的程式內
總共對哪些資料流做了訂閱,可以一目瞭然
this.subscription.add(getData1$);
this.subscription.add(getData2$);
this.subscription.add(getData3$);